package cn.tedu.csmall.resource.controller;

import cn.tedu.csmall.commons.ex.ServiceException;
import cn.tedu.csmall.commons.web.ServiceCode;
import cn.tedu.csmall.resource.pojo.vo.UploadResult;
import cn.tedu.csmall.commons.web.JsonResult;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/resource/")
@Slf4j
@Api("文件上传模块")
public class ResourceController {

    @Value("${csmall.upload.host}")
    private String host;
    @Value("${csmall.upload.base-dir}")
    private String uploadBaseDir;
    @Value("${csmall.upload.product-image.max-size}")
    private Integer productImageMaxSize;
    @Value("${csmall.upload.avatar-image.max-size}")
    private Integer avatarImageMaxSize;
    @Value("${csmall.upload.product-image.types}")
    private List<String> productImageValidTypes;
    @Value("${csmall.upload.avatar-image.types}")
    private List<String> avatarImageValidTypes;

    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/");
    private final String productImageDirName = "product-image/";
    private final String avatarImageDirName = "avatar-image/";

    public ResourceController() {
        log.debug("创建控制器类对象：ResourceController");
    }

    @PostMapping("/upload/image/product")
    @ApiOperation("上传商品图片")
    @ApiOperationSupport(order = 100)
    public JsonResult<UploadResult> uploadProductImage(@RequestParam(value = "file") MultipartFile multipartFile) throws Throwable {

        long size = multipartFile.getSize();
        if (size > productImageMaxSize * 1024 * 1024) {
            String message = "上传商品图片失败，不允许使用超过" + productImageMaxSize + "MB的图片文件！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPLOAD_EXCEED_MAX_SIZE, message);
        }

        String contentType = multipartFile.getContentType();
        if (!productImageValidTypes.contains(contentType)) {
            String message = "上传商品图片失败，请使用以下类型的图片文件：" + productImageValidTypes;
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPLOAD_INVALID_TYPE, message);
        }

        String dirName = simpleDateFormat.format(new Date());// 将现在的日期转换成指定类型的字符串作为目录名称  2023/07/14/
        File productImageDir = new File(uploadBaseDir, productImageDirName);// D:\files\csmall-upload\product-image
        File uploadDir = new File(productImageDir, dirName);// D:\files\csmall-upload\product-image\2023\07\14

        if (!uploadDir.exists()) {
            boolean success = uploadDir.mkdirs();
            if (success) {
                log.debug("创建文件夹{}成功！", uploadDir);
            } else {
                log.debug("创建文件夹失败！");
            }
        }

        // 文件名改为随机UUID+原始文件名后缀（b63aaf31-4ea6-4691-ba18-281ff173c401.jpg）
        String newFileName = UUID.randomUUID().toString();
        String originalFilename = multipartFile.getOriginalFilename();
        assert originalFilename != null;
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFullFileName = newFileName + suffix;
        File newFile = new File(uploadDir, newFullFileName);// D:\files\csmall-upload\product-image\2023\07\14\b63aaf31-4ea6-4691-ba18-281ff173c401.jpg

        multipartFile.transferTo(newFile);// 将 multipartFile 对应的文件上传到 newFile 目录下

        String url = new StringBuilder()
                .append(host)// http://localhost:8082/
                .append(productImageDirName)// http://localhost:8082/product-image/
                .append(dirName)// http://localhost:8082/product-image/2023/07/14
                .append(newFullFileName)// http://localhost:8082/product-image/2023/07/14/xxx.png
                .toString();

        UploadResult uploadResult = new UploadResult();
        uploadResult.setUrl(url);
        uploadResult.setFileSize(size);
        uploadResult.setContentType(contentType);
        uploadResult.setFileName(newFullFileName);
        return JsonResult.success(uploadResult);
    }

    @PostMapping("/upload/image/avatar")
    @ApiOperation("上传头像图片")
    @ApiOperationSupport(order = 200)
    public JsonResult<UploadResult> uploadAvatarImage(@RequestParam(value = "file") MultipartFile multipartFile) throws Throwable {

        long size = multipartFile.getSize();
        if (size > avatarImageMaxSize * 1024 * 1024) {
            String message = "上传头像图片失败，不允许使用超过" + avatarImageMaxSize + "MB的图片文件！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPLOAD_EXCEED_MAX_SIZE, message);
        }

        String contentType = multipartFile.getContentType();
        if (!avatarImageValidTypes.contains(contentType)) {
            String message = "上传头像图片失败，请使用以下类型的图片文件：" + avatarImageValidTypes;
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPLOAD_INVALID_TYPE, message);
        }

        String dirName = simpleDateFormat.format(new Date());
        File productImageDir = new File(uploadBaseDir, avatarImageDirName);
        File uploadDir = new File(productImageDir, dirName);

        if (!uploadDir.exists()) {
            boolean success = uploadDir.mkdirs();
            if (success) {
                log.debug("创建文件夹{}成功！", uploadDir);
            } else {
                log.debug("创建文件夹失败！");
            }
        }

        String newFileName = UUID.randomUUID().toString();
        String originalFilename = multipartFile.getOriginalFilename();
        assert originalFilename != null;
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFullFileName = newFileName + suffix;
        File newFile = new File(uploadDir, newFullFileName);

        multipartFile.transferTo(newFile);

        String url = new StringBuilder()
                .append(host)
                .append(avatarImageDirName)
                .append(dirName)
                .append(newFullFileName)
                .toString();

        UploadResult uploadResult = new UploadResult();
        uploadResult.setUrl(url);
        uploadResult.setFileSize(size);
        uploadResult.setContentType(contentType);
        uploadResult.setFileName(newFullFileName);
        return JsonResult.success(uploadResult);
    }
}
